package cn.mrcode.wxsdk.core.dialogue.service;

import cn.mrcode.wxsdk.core.dialogue.common.InMsgParaser;
import cn.mrcode.wxsdk.core.dialogue.common.PublicAccount;
import cn.mrcode.wxsdk.core.dialogue.common.SignUtil;
import cn.mrcode.wxsdk.core.dialogue.hander.DefaultInMessageProcessingHandler;
import cn.mrcode.wxsdk.core.dialogue.hander.InMessageProcessingHandler;
import cn.mrcode.wxsdk.core.dialogue.protocol.msg.InMsg;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 微信接入 入口类
 * @author zhuqiang
 * @version V1.0
 * @date 2015/9/29 14:53
 */
public class Access {
    private static Logger log = LoggerFactory.getLogger(Access.class);
    private static InMessageProcessingHandler inMessageProcessingHandler = new DefaultInMessageProcessingHandler();
    /**
     * @param inHanderT 选传：消息处理服务的扩展参数
     * @param account 必传参数：微信公众账户
     * @param signature 必传：微信回调的加密签名
     * @param timestamp 必传：微信回调的时间戳
     * @param nonce 必传：微信回调的随机字符串
     * @param echostr 必传：随机字符串,接入的时候校验
     * @param request
     * @param response
     * @param <T>
     */
    public static <T> void in(T inHanderT, PublicAccount account, String signature, String timestamp, String nonce, String echostr, HttpServletRequest request, HttpServletResponse response) {
//        String accesstoken = CommonService.getAccesstoken(account.getAppID(), account.getAppSecret());
        String outPut = "error";
        try {
            // 请求校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
            if (StringUtils.isNotBlank(signature) && SignUtil.checkSignature(account.getToken(), signature, timestamp, nonce)) {
                if (StringUtils.isNotBlank(echostr)) {
                    outPut = echostr;
                } else {
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("text/xml");
                    // 本次请求 xml数据
                    String reqMsgXml = SignUtil.inputStream2String(request.getInputStream());
                    log.debug("入口：输入消息:[" + reqMsgXml + "]");
                    // 本次请求 xml 解析后的 ReqMsg 对象
                    InMsg reqMsg = InMsgParaser.parse(reqMsgXml);
                    log.debug("入口：消息解析对象" + JSON.toJSONString(reqMsg));
                    outPut = inMessageProcessingHandler.processing(reqMsg, account.getAppID(), inHanderT);
                }
            } else {
                log.info("验证不通过！");
            }
            if (outPut != null) {
                log.info(JSON.toJSONString(outPut));
                response.getWriter().write(outPut);
                response.flushBuffer();
            } else {
                response.getWriter().write("");
                log.info("没找到对应的消息");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static InMessageProcessingHandler getInMessageProcessingHandler() {
        return inMessageProcessingHandler;
    }

    /**
     * 指定该工具类：使用的消息服务
     * @param inMessageProcessingHandler 一般在生产中都需要自己实现该接口，编写自己的消息处理器
     */
    public static void setInMessageProcessingHandler(InMessageProcessingHandler inMessageProcessingHandler) {
        Access.inMessageProcessingHandler = inMessageProcessingHandler;
    }
}
